package com.itheima.reggie.builder;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.exception.CustomException;
import com.itheima.reggie.service.AddressBookService;
import com.itheima.reggie.service.OrderDetailService;
import com.itheima.reggie.service.ShoppingCartService;
import com.itheima.reggie.service.UserService;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/*
把组合实体类构建出来
 */
public class FullOrderDataBuilder {
    private ShoppingCartService shoppingCartService;
    private OrderDetailService orderDetailService;
    private UserService userService;
    private AddressBookService addressBookService;
    private FullOrderData fullOrderData;
    private Orders orders;
    private AtomicInteger amount = new AtomicInteger(0);//如果放在方法里面为局部变量，一个方法不能拿到另一个方法的局部变量，每次拿值就是不一样，

    //所有说解决办法要么再次传参，要么就是提升作用域。此时多个线程操作的就不一样了，之前在方法内部每个线程操作自己的成员变量，没有线程安全问题
    //现在这个变量被多个方法所使用，操作一个共享的数据，就可以采用这种原子类来操作
    /*
    构造器要构建时需要orderserviceimpl中的Autowired内容;
        1.把当前类交给spring管理，然后Autowired
        2.构造器传参（这里使用第二种）
     */
    public FullOrderDataBuilder(ShoppingCartService shoppingCartService, OrderDetailService orderDetailService, UserService userService, AddressBookService addressBookService,Orders orders){
        this.shoppingCartService=shoppingCartService;
        this.orderDetailService=orderDetailService;
        this.userService=userService;
        this.addressBookService=addressBookService;
        //创建组合实体类对象
        this.fullOrderData=new FullOrderData();
        this.orders=orders;

    }
    public FullOrderDataBuilder builderOrder(){//构建订单实体类

        return this;
    }

    public FullOrderDataBuilder builderOrderDetail(){
        LambdaQueryWrapper<ShoppingCart> cartlqw = new LambdaQueryWrapper<>();
        cartlqw.eq(ShoppingCart::getUserId, BaseContext.getCurrentId());

        List<ShoppingCart> shoppingCarts = shoppingCartService.list(cartlqw);
        if (shoppingCarts==null && shoppingCarts.size()==0){
            throw new CustomException("当前购物车为空，不能下单");
        }
        List<OrderDetail> orderDetailList = shoppingCarts.stream().map((cart) -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setName(cart.getName());
            orderDetail.setImage(cart.getImage());
            orderDetail.setOrderId(orders.getId());
            orderDetail.setDishId(cart.getDishId());
            orderDetail.setSetmealId(cart.getSetmealId());
            orderDetail.setDishFlavor(cart.getDishFlavor());
            orderDetail.setNumber(cart.getNumber());
            orderDetail.setAmount(cart.getAmount());
            //amount+=单价*数量
            amount.addAndGet(cart.getAmount().multiply(new BigDecimal(cart.getNumber())).intValue());//总价,就是累加
            return orderDetail;
        }).collect(Collectors.toList());
        fullOrderData.setOrderDetailList(orderDetailList);
        return this;
    }

    public FullOrderData builder(){
        /*
            订单表
         */
        LambdaQueryWrapper<AddressBook> addresslqw = new LambdaQueryWrapper<>();
        addresslqw.eq(AddressBook::getId, orders.getAddressBookId());
        AddressBook addressBook = addressBookService.getOne(addresslqw);
        if (addressBook==null){
            throw new CustomException("用户地址信息有误，不能下单");
        }
        orders.setId(orders.getId());
        orders.setNumber(String.valueOf(orders.getId()));
        orders.setStatus(2);
        orders.setUserId(BaseContext.getCurrentId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setAmount(new BigDecimal(amount.get()));
        orders.setCheckoutTime(LocalDateTime.now());

        User user = userService.getById(BaseContext.getCurrentId());

        orders.setUserName(user.getName());
        orders.setPhone(addressBook.getPhone());
        orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())
                + (addressBook.getCityName() == null ? "" : addressBook.getCityName())
                + (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())
                + (addressBook.getDetail() == null ? "" : addressBook.getDetail()));
        orders.setConsignee(addressBook.getConsignee());
        fullOrderData.setOrders(orders);
        return fullOrderData;
    }

}
